from tkinter.filedialog import askdirectory
from tkinter import scrolledtext
import threading
import tkinter as tk
import tkinter.ttk
import datetime
import paramiko 
import pathlib
import time
import re
import os


# ui
class my_ui:

    defult_remote_folder = r"/home/万裕青/遥感数据/Sentinel2L1cZip"
    width, height = 780, 620
    line_height = 50
    temp_file_name = ""
   

    def __init__(self):

        self.get_window()
        self.zip_folder = tk.StringVar()
        self.remote_folder = tk.StringVar()
        self.remote_folder.set(self.defult_remote_folder)

        line_iter = iter(range(50))
        
        self.zip_folder_frame(next(line_iter))
        self.remote_folder_frame(next(line_iter))
        self.start_button_frame(next(line_iter))
        self.progressbar_frame(next(line_iter))
        self.print_running_frame(next(line_iter))

        self.window.mainloop()

    def get_window(self):
        self.window = tk.Tk()
        self.window.title('Sentinel-2数据（L1C）上传工具')
        screenwidth = self.window.winfo_screenwidth() # 屏幕宽度
        screenheight = self.window.winfo_screenheight() # 屏幕高度
        x = int((screenwidth - self.width) / 2)
        y = int((screenheight - self.height) / 2)
        locat = f"{self.width}x{self.height}+{x}+{y}"
        self.window.geometry(locat) # 大小以及位置
        self.window.resizable(0,0) 
        return

    def zip_folder_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))

        tk.Label(
            frame,text="本地目录",font=('宋体','14','bold'),height=3
        ).grid(column=next(column_iter),row=0,sticky='we') 
        
        self.local_dir=tk.Entry(
            frame,
            width=53,
            background = 'white',
            borderwidth = 3,
            relief = 'sunken',
            insertwidth = 3,
            font = ('Helvetica', '14', 'bold'),
            textvariable=self.zip_folder,
            selectforeground = 'red',
            selectbackground = 'blue',
            selectborderwidth = 0,
            show=None
        )  
        self.local_dir.grid(column=next(column_iter),row=0,sticky='we')
        self.select_dir_button=tk.Button(
            frame,
            text="选择目录",
            font=('','14','bold'), 
            bg="#50b7c1",
            command=lambda: self.zip_folder.set(askdirectory().replace('/','\\')),
        ) 
        self.select_dir_button.grid(column=next(column_iter),row=0,sticky='we')
        return

    def remote_folder_frame(self, row):
        frame=tkinter.ttk.Frame(self.window,width=self.width)
        frame.place(x=0,y=self.line_height*row)

        tk.Label(
            frame,text="远程目录",font=('宋体','14','bold'),height=3
        ).grid(column=0,row=0,sticky='we')  #定义一个标签lable
        self.remote_dir=tk.Entry(
            frame,
            width=53,
            background = 'white',
            borderwidth = 3,
            relief = 'sunken',
            insertwidth = 3,
            font = ('', '14', 'bold'),
            textvariable=self.remote_folder,
            selectforeground = 'red',
            selectbackground = 'blue',
            selectborderwidth = 0,
            show=None
        )  
        self.remote_dir.grid(column=1,row=0,sticky='we')
        return

    def start_button_frame(self, row):
        s = tkinter.ttk.Style()
        # s.configure("1.TFrame",background='white')
        frame=tkinter.ttk.Frame(
            self.window,style="1.TFrame",width=self.width,height=60)
        frame.place(x=0,y=self.line_height*row)
        self.start_button=tk.Button(
            frame,
            text="开始上传",
            font=('','14','bold'),
            bg="#50b7c1",
            command=lambda: self.thread_it(self.run_main),
        )
        self.start_button.place(relx=0.5,rely=0.5,anchor='center')
        return

    def progressbar_frame(self,row):
        frame=tkinter.ttk.Frame(self.window,width=self.width)
        frame.place(x=0,y=self.line_height*row)
        column_iter = iter(range(10))

        tk.Label(
            frame,text="运行进度",font=('宋体','14','bold'),height=3,
        ).grid(column=next(column_iter),row=0,sticky='we')  

        self.progressbar = tkinter.ttk.Progressbar(
            frame,
            length=680,
            # maximum=100,
            value=0,
            cursor='spider',
            mode="determinate",
            # mode="indeterminate",
            orient=tk.HORIZONTAL,
        )
        self.progressbar.grid(column=next(column_iter),row=0,sticky='we')    
        return

    def print_running_frame(self, row):
        frame=tkinter.ttk.Frame(self.window)
        frame.place(x=0,y=60*row)
        tk.Label(
            frame,text="运行信息",font=('宋体','14','bold'),
        ).grid(column=0,row=0,sticky='we')
        # ).pack(side=tk.LEFT+tk.TOP,fill=tk.NONE)
        self.scrolled_text = scrolledtext.ScrolledText(
			frame, 
			state='normal',
            wrap = tk.WORD,
            # font=('Times New Roman', 12),
            font="TkFixedFont",
			width=95, 
			height=28,
        ) 
        self.scrolled_text.tag_config('INFO', foreground='black')
        self.scrolled_text.tag_config('DEBUG', foreground='gray')
        self.scrolled_text.tag_config('WARNING', foreground='orange')
        self.scrolled_text.tag_config('ERROR', foreground='red')
        self.scrolled_text.tag_config('CRITICAL', foreground='red', underline=1)
        self.scrolled_text.grid(column=1,row=0,rowspan=20,sticky='we')
        # self.scrolled_text.pack(side=tk.LEFT,fill=tk.NONE) 
        return

    def thread_it(self,func,*args):
        # 线程
        t = threading.Thread(target=func, args=args)
        # 守护 !!!
        t.setDaemon(True)
        # 启动
        t.start()
        # 阻塞--卡死界面！
        # t.join()
        return

    def update_info(self,string):
        datetime_str = datetime.datetime.now().strftime('%H:%M:%S')
        string = f"{datetime_str}>{string} \n"
        self.scrolled_text.insert(tk.END, string)
        self.scrolled_text.see(tk.END)
        self.scrolled_text.focus()
        self.window.update()
        return

    def run_main(self):
        start = time.time()
        self.scrolled_text.configure(state='normal')
        self.scrolled_text.delete(0.0, tkinter.END)
        self.window.update()

        local_dir = self.local_dir.get()
        if not os.path.exists(local_dir):
            tk.messagebox.showwarning('Waring', '未选择本地目录！')
            return
        self.update_info(f"本地目录：{local_dir}")

        file_paths = [
            os.path.join(local_dir,name)
            for name in os.listdir(local_dir)
            if re.match("^S2[AB]_MSIL1C_.*\.zip$",name)
        ]
        self.update_info(f"{len(file_paths)}个文件")
        
        remote_dir = self.remote_dir.get()
        if remote_dir == "":
            tk.messagebox.showerror('Error', '未选择远程目录！')
            return
        self.update_info(f"远程目录:{remote_dir}")

        client = paramiko.SSHClient()
        client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        client.connect(hostname="192.168.2.172",port=22,username="root",password="DELL123dell")
        sftp: paramiko.SFTPClient = client.open_sftp()
        self.update_info("连接服务器:192.168.2.172")
    
        self.progressbar["maximum"] = len(file_paths) 
        for index,file_path in enumerate(file_paths):
            file_name  = os.path.basename(file_path)
            date_str = file_name.split("_")[2][:8]
            date_dir = pathlib.PurePosixPath(remote_dir,date_str)
            try:
                sftp.stat(str(date_dir))
            except:
                sftp.mkdir(str(date_dir))

            remote_path = pathlib.PurePosixPath(date_dir,file_name)
            try:
                stat = sftp.stat(str(remote_path))
                f_local = open(file_path)
                f_remote = sftp.open(str(remote_path), "a")
                f_local.seek(stat.st_size)
                tmp_buffer = f_local.read(100000)
                while tmp_buffer:
                    f_remote.write(tmp_buffer)
                    tmp_buffer = f_local.read(100000)
                f_remote.close()
                f_local.close()
                self.update_info(f"上传完成：{file_name}")
            except:
                self.temp_file_name = file_name
                # self.update_info(f"\n")
                datetime_str = datetime.datetime.now().strftime('%H:%M:%S')
                sftp.put(file_path,str(remote_path),callback=self._Callback)
                print_index = float(self.scrolled_text.index(tk.END))
                self.scrolled_text.delete(print_index-1.0,print_index)
                self.scrolled_text.insert(tk.END, f"\n{datetime_str}>上传完成：{file_name}\n")
                self.scrolled_text.see(tk.END)
                self.window.update()

            self.progressbar["value"] = index + 1  
      
        sftp.close()
        client.close()
        tk.messagebox.showinfo('Message', f'下载完成！耗时：{time.time()-start}')
        return
    
    def _Callback(self,a=10,b=10):
        percent = round(a*100./int(b),2)
        datetime_str = datetime.datetime.now().strftime('%H:%M:%S')
        if  percent in [i*20.00 for i in range(6)] :
            index = float(self.scrolled_text.index(tk.END))
            self.scrolled_text.delete(index-1.0,index)
            string = f'\n{datetime_str}>{self.temp_file_name} {round(a/1024./1024,2)}M {percent}%'
            self.scrolled_text.insert(index, string)
            self.scrolled_text.see(index)
            self.window.update()
        return


if __name__ == "__main__":
    # command=r"net use Z: \\192.168.2.172\root DELL123dell /user:root"
    # os.system(command)
    my_ui()